﻿Imports System.IO
Imports System.Text.RegularExpressions
Imports System.Windows.Forms

Namespace Unreal

    Public Class UnrealClass

        Private _fullname As String
        ReadOnly Property FullName As String
            Get
                Return _fullname
            End Get
        End Property

        Private _name As String
        ReadOnly Property Name As String
            Get
                Return _name
            End Get
        End Property

        Private _parentname As String
        ReadOnly Property ParentName As String
            Get
                Return _parentname
            End Get
        End Property

        Private _functions As List(Of UnrealFunction)
        ReadOnly Property Functions As List(Of UnrealFunction)
            Get
                Return _functions
            End Get
        End Property

        Private _variables As List(Of UnrealVariable)
        ReadOnly Property Variables As List(Of UnrealVariable)
            Get
                Return _variables
            End Get
        End Property

        Private _rootnode As TreeNode
        ReadOnly Property RootNode As TreeNode
            Get
                Return _rootnode
            End Get
        End Property

        Private _completedparsing As Boolean = False
        ReadOnly Property CompletedParsing As Boolean
            Get
                Return _completedparsing
            End Get
        End Property

        Public Sub New(ByRef fullname As String)
            _fullname = fullname
            _name = ReadClassName(fullname)
            _rootnode = New TreeNode(Name)
        End Sub

        Private Function ReadClassName(ByRef fullname As String) As String
            If fullname.EndsWith("\") Then
                fullname = fullname.Substring(0, fullname.Count)
            End If

            Dim classname As String =
                fullname.Substring(fullname.LastIndexOf("\") + 1,
                                   fullname.Count -
                                   fullname.LastIndexOf("\") - 1).Replace(".uc", "")

            Return classname

        End Function

        Public Sub Parse()
            _parentname = ParseOutParentClassName(FullName)
            _functions = ParseOutFunctions(FullName)
            _variables = ParseOutVariables(FullName)

            _completedparsing = True
        End Sub

        Public Function GetFunctionBySignature(ByRef func_signature As String) As UnrealFunction
            For Each func In _functions
                If func_signature = func.Signature Then
                    Return func
                End If
            Next

            Return Nothing
        End Function

        Public Function GetVariableBySignature(ByRef var_signature As String) As UnrealVariable
            For Each var In _variables
                If var_signature = var.Signature Then
                    Return var
                End If
            Next

            Return Nothing
        End Function

        Private Function ParseOutParentClassName(ByRef fullname As String) As String
            Dim reader As New StreamReader(fullname)
            Dim readline As String
            Dim re As New Regex("^\w*class.*extends.*$")

            readline = reader.ReadLine()
            While reader.Peek <> -1
                readline = reader.ReadLine()
                If re.IsMatch(readline) Then
                    Exit While
                End If
            End While

            reader.Close()

            Dim class_def As String = "No Parent"
            If re.IsMatch(readline) Then
                class_def = re.Match(readline).ToString()
                class_def = class_def.Substring(class_def.IndexOf("extends ") +
                        "extends ".Length, class_def.Length -
                        class_def.IndexOf("extends ") - "extends ".Length)
            End If

            Return class_def
        End Function

        Private Function ParseOutFunctions(ByRef fullname As String) As List(Of UnrealFunction)
            Dim funcs As New List(Of UnrealFunction)
            Dim reader As New StreamReader(fullname)
            Dim contents() As String = reader.ReadToEnd().Split(vbLf.ToCharArray())
            reader.Close()

            Dim linenum As Integer = 0
            Dim re As New Regex("^.*(function|virtual|void).*\(.*\).*$")
            For Each line As String In contents
                linenum += 1
                If re.IsMatch(line) Then

                    Dim sig As String = line.Replace(vbTab, " ").Replace(";", "")
                    _rootnode.Nodes.Add(sig)
                    funcs.Add(New UnrealFunction(sig, linenum))

                End If
            Next

            Return funcs
        End Function

        Private Function ParseOutVariables(ByRef fullname As String) As List(Of UnrealVariable)
            Dim vars As New List(Of UnrealVariable)

            Dim reader As New StreamReader(fullname)
            Dim contents() As String = reader.ReadToEnd().Split(vbLf.ToCharArray())
            reader.Close()

            Dim linenum As Integer = 0
            Dim re As New Regex("^\w*var\(*\)*.*;")
            For Each line As String In contents
                linenum += 1
                If re.IsMatch(line) Then

                    Dim sig As String = line.Replace(vbTab, " ").Replace(";", "")
                    _rootnode.Nodes.Add(sig)
                    vars.Add(New UnrealVariable(sig, linenum))

                End If
            Next

            Return vars
        End Function

    End Class

End Namespace